﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Web.Security;
using SIMCObjetoNegocio;
using System.Configuration;
using System.Text.RegularExpressions;

namespace WcfServicioSeguridad
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        SimcMembershipProvider provider;

        public Service1()
        {
            provider = new SimcMembershipProvider();
            //provider.Initialize("SimcMembershipProvider",System.Configuration.ConfigurationManager.AppSettings);
            provider = (SimcMembershipProvider)Membership.Providers["SimcMembershipProvider"];
        }

        public void Iniciar()
        {
            provider = new SimcMembershipProvider();
            //provider.Initialize("SimcMembershipProvider",System.Configuration.ConfigurationManager.AppSettings);
            provider = (SimcMembershipProvider)Membership.Providers["SimcMembershipProvider"];
        }

        public bool ValidarUsuario(string login, string pass)
        {
            return provider.ValidateUser(login, pass);
        }       

        public string ApplicationName()
        {
            return provider.ApplicationName;
        }

        public bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            return provider.ChangePassword(username, oldPassword, newPassword);
        }

        public bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            return provider.ChangePasswordQuestionAndAnswer(username, password, newPasswordQuestion, newPasswordAnswer);
        }

        public bool CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            MembershipUser user = provider.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status);
            if (user != null)
            {
                return true;
            }
            return false;
        }
        public bool CreateUsuario(string username,
                                            string password,
                                            string email,
                                            string passwordQuestion,
                                            string passwordAnswer,
                                            bool isApproved,
                                            object providerUserKey,
                                            string telefono,
                                            string Nombre,
                                            string Apellido)
        {
            Usuario user = provider.CreateUsuario(username,
                                             password,
                                             email,
                                             passwordQuestion,
                                             passwordAnswer,
                                             isApproved,
                                             providerUserKey,
                                             MembershipCreateStatus.Success,
                                             telefono,
                                             Nombre,
                                             Apellido);
             if (user != null)
             {
                 return true;
             }
             return false;
        }

        public bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            return provider.DeleteUser(username, deleteAllRelatedData);
        }

        public  bool EnablePasswordReset()
        {
            return provider.EnablePasswordReset; 
        }

        public bool EnablePasswordRetrieval()
        {
             return provider.EnablePasswordRetrieval;
        }

        public int GetNumberOfUsersOnline()
        {
            return provider.GetNumberOfUsersOnline();
        }

        public  string GetPassword(string username, string answer)
        {
            return provider.GetPassword(username, answer);
        }      

        public int MaxInvalidPasswordAttempts()
        {
            return provider.MaxInvalidPasswordAttempts;
        }

        public  int MinRequiredNonAlphanumericCharacters()
        {
             return provider.MinRequiredNonAlphanumericCharacters;
        }

        public  int MinRequiredPasswordLength()
        {
            return provider.MinRequiredPasswordLength;
        }

        public  int PasswordAttemptWindow()
        {
            return provider.PasswordAttemptWindow;
        }

        public  MembershipPasswordFormat PasswordFormat()
        {
             return provider.PasswordFormat;
        }

        public  string PasswordStrengthRegularExpression()
        {
             return provider.PasswordStrengthRegularExpression;
        }

        public  bool RequiresQuestionAndAnswer()
        {
             return provider.RequiresQuestionAndAnswer;
        }

        public  bool RequiresUniqueEmail()
        {
            return provider.RequiresUniqueEmail;
        }

        public string ResetPassword(string username, string answer)
        {
            return provider.ResetPassword(username, answer);
        }

        public  bool UnlockUser(string userName)
        {
            return provider.UnlockUser(userName);
        }
        
        public void BloquearUsuario(string nombreUsuario)
        {
            MembershipUser user = provider.GetUser(nombreUsuario, false);

            user.IsApproved = false;

            provider.UpdateUser(user);
        }

        public void DesbloquearUsuario(string nombreUsuario)
        {
            MembershipUser user = provider.GetUser(nombreUsuario, false);

            user.IsApproved = true;

            provider.UpdateUser(user);
        }


        public void ValidatePassword(string password, string username)
        {
            if (password.Length < provider.MinRequiredPasswordLength)
            {
                throw new ArgumentException("La contraseña debe tener mas de " + provider.MinRequiredPasswordLength + " caracteres.");
            }
            if (password.Contains(username))
            {
                throw new ArgumentException("El nombre de usuario no debe estar incluido en la contraseña.");
            }
            if (username.Contains(password))
            {
                throw new ArgumentException("La contraseña no debe estar incluida en el nombre de usuario.");
            }
            if (username.Contains(" "))
            {
                throw new ArgumentException("El nombre de usuario no debe tener espacios.");
            }
            if (password.Contains(" "))
            {
                throw new ArgumentException("La contraseña no debe tener espacios.");
            }

            int cantConjuntos = 0;
            try
            {
                cantConjuntos = Convert.ToInt32(ConfigurationManager.AppSettings["CantidadConjuntosPassword"]);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("Cantidad invalida de conjuntos en webConfig");
            }

            if (!this.TieneMinusculas(password) && (cantConjuntos > 0))
            {
                throw new ArgumentException("La contraseña debe tener al menos una letra minuscula.");
            }
            if (!this.TieneMayusculas(password) && (cantConjuntos > 1))
            {
                throw new ArgumentException("La contraseña debe tener al menos una letra mayuscula.");
            }
            if (!this.TieneNumeros(password) && (cantConjuntos > 2))
            {
                throw new ArgumentException("La contraseña debe tener al menos un numero.");
            }
            if (!this.TieneCaracteresEspeciales(password) && (cantConjuntos > 3))
            {
                throw new ArgumentException("La contraseña debe tener al menos un caracter especial");
            }
        }

        private bool TieneMinusculas(string strToCheck)
        {
            Regex objAlphaNumericPattern = new Regex("[+a-z]");

            return objAlphaNumericPattern.IsMatch(strToCheck);
        }

        private bool TieneMayusculas(string strToCheck)
        {
            Regex objAlphaNumericPattern = new Regex("[+A-Z]");

            return objAlphaNumericPattern.IsMatch(strToCheck);
        }

        private bool TieneNumeros(string strToCheck)
        {
            Regex objAlphaNumericPattern = new Regex("[+0-9]");

            return objAlphaNumericPattern.IsMatch(strToCheck);
        }

        private bool TieneCaracteresEspeciales(string strToCheck)
        {
            Regex objAlphaNumericPattern = new Regex("[+#$&=*]");

            return objAlphaNumericPattern.IsMatch(strToCheck);
        }

        private bool TieneCaracteresProhibidos(string strToCheck)
        {
            Regex objAlphaNumericPattern = new Regex("[+#$&=*]");

            return objAlphaNumericPattern.IsMatch(strToCheck);
        }

        // Inicio Lili
        public Usuario GetUsuario(string login, bool userIsOnline)
        {
            return provider.GetUsuario(login, userIsOnline);
        }

        public List<Usuario> GetUsuarioPorLogin(string Login)
        {
            return provider.GetUsuarioPorLogin(Login);
        }

        public List<Usuario> GetUsuarioPorEmail(string Email)
        {
            return provider.GetUsuarioPorEmail(Email);
        }

        public List<Usuario> GetUsuariosPorNombre(string Nombre)
        {
            return provider.GetUsuariosPorNombre(Nombre);
        }

        // Fin Lili


        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        public void UpdateUsuario(Usuario user)
        {
            provider.UpdateUsuario(user);
        }
    }
}
